﻿using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Input;
using System.Xml.Linq;
using CommunityToolkit.Mvvm.Input;
using Elastic.Clients.Elasticsearch;
using Elastic.Clients.Elasticsearch.Aggregations;
using Elastic.Clients.Elasticsearch.QueryDsl;
using Elastic.Transport;
using HtmlAgilityPack;
using ICSharpCode.AvalonEdit;
using MahApps.Metro.Controls.Dialogs;
using Newtonsoft.Json;
using Notifications.Wpf;
using Serilog;
using VideoTools.Extension;
using VideoTools.Services;
using VideoTools.SubtitleView;
using VideoTools.Util;
using VideoTools.vo;
using ComboBox = System.Windows.Controls.ComboBox;
using TextBox = System.Windows.Controls.TextBox;

namespace VideoTools.Commands
{
    public class SearchSubtitleCommands : NotifyPropertyBase
    {
        private static readonly string CREATE_TIME_TEXT = "导入时间";
        private static readonly string START_TIME_TEXT = "起始时间";
        private static readonly string END_TIME_TEXT = "结束时间";
        private static readonly string SUBTITLE_TEXT = "[选中搜索结果自动复制到剪贴板]";
        private static readonly string SUBTITLE_COUNT_TEXT = "字幕数量";
        private static readonly string NO_NAME_TEXT = "---";
        private static volatile SearchSubtitleCommands _instance;
        private static readonly object SyncRoot = new object();
        public static readonly string NAME_INDEX = "name";
        public static readonly string SUBTITLE_INDEX = "subtitle";
        public static readonly string ADDRESS_INDEX = "vaddress";
        private bool searchSubtitle = false;
        private ElasticsearchClient client = null;
        private long subtitleCount = 0;
        private long nameCount = 0;
        private static readonly int SIZE = 2000;

        private static int AddressRows = 8;
        private static int AddressCols = 8;
        private static readonly HttpClient httpClient = new HttpClient();

        public static SearchSubtitleCommands Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (SyncRoot)
                    {
                        if (_instance == null)
                        {
                            _instance = new SearchSubtitleCommands();
                        }
                    }
                }

                return _instance;
            }
        }

        private SearchSubtitleCommands()
        {
            foreach (VideoType vt in Utils.GetAllEnumValues<VideoType>())
            {
                VideoTypes.Add(vt);
            }
            SearchNameHistorys = AppConfig.Instance.SearchNameHistorys;
            NameHistorys = AppConfig.Instance.NameHistorys;
            VideoHistorys = AppConfig.Instance.VideoHistorys;
            AppConfig config = AppConfig.Instance;
            if (
                !(
                    config == null
                    || config.EsAddress == null
                    || config.EsFingerprint == null
                    || config.EsUserName == null
                    || config.EsPassword == null
                    || config.EsAddress.Length == 0
                    || config.EsFingerprint.Length == 0
                    || config.EsUserName.Length == 0
                    || config.EsPassword.Length == 0
                )
            )
            {
                var settings = new ElasticsearchClientSettings(
                    new Uri(AppConfig.Instance.EsAddress)
                )
                    .CertificateFingerprint(AppConfig.Instance.EsFingerprint)
                    .Authentication(
                        new BasicAuthentication(
                            AppConfig.Instance.EsUserName,
                            AppConfig.Instance.EsPassword
                        )
                    );

                client = new ElasticsearchClient(settings);
                Elastic.Clients.Elasticsearch.CountResponse countResponse = client.Count(
                    new Elastic.Clients.Elasticsearch.CountRequest<SearchSubtitle>(SUBTITLE_INDEX)
                );

                if (countResponse.IsValidResponse)
                {
                    subtitleCount = countResponse.Count;
                    SubtitleCount = $"字幕总量：{subtitleCount}";
                }

                Elastic.Clients.Elasticsearch.SearchResponse<SubtitleName> response =
                    client.Search<SubtitleName>(s =>
                        s.Index(NAME_INDEX)
                            .From(0)
                            .Size(1)
                            .Sort(s =>
                                s.Field(
                                    "nameId",
                                    f => f.Order(Elastic.Clients.Elasticsearch.SortOrder.Desc)
                                )
                            )
                    );

                if (response.IsValidResponse)
                {
                    foreach (SubtitleName name in response.Documents)
                    {
                        nameCount = name.nameId;
                        SearchCount = $"结果数量：{nameCount}";
                    }
                }
            }
        }

        private ICommand _SearchSubtitleCommand;
        private ICommand _OpenConfigEsCommand;
        private ICommand _OpenDeleteSubtitleCommand;
        private ICommand _DeleteSubtitleCommand;
        private ICommand _StatisticSubtitleCommand;
        private ICommand _ImportSubtitleCommand;
        private ICommand _OpenImportSubtitleCommand;
        private ICommand _ImportOpenFolderCommand;

        private ICommand _NameToSearchNameCommand;
        private ICommand _SearchNameToNameCommand;

        private ICommand _SearchNameCommand;

        private ICommand _VideoToSearchNameCommand;
        private ICommand _VideoToNameCommand;
        private ICommand _NameToVideoCommand;
        private ICommand _SearchNameToVideoCommand;

        private ICommand _SearchVideoCommand;
        private ICommand _ConfigEsCommand;
        private ICommand _SubtitleClickCommand;
        private ICommand _SubtitleDoubleClickCommand;
        private ICommand _ChangeVideoTypeCommand;
        private ICommand _ImportVideoInfoCommand;
        private ICommand _SpideQdairepListCommand;

        public ICommand SpideQdairepListCommand =>
            _SpideQdairepListCommand
            ?? (
                _SpideQdairepListCommand = new RelayCommand<object>(o =>
                {
                    List<SubtitleTypeAndPages> typeAndPages = new List<SubtitleTypeAndPages>();
                    //typeAndPages.Add(new TypeAndPages(1, 0));
                    typeAndPages.Add(new SubtitleTypeAndPages(2, 1));
                    string listAddress = "https://www.qdairep.com/filmlist/{0}-{1}.html";
                    List<SubtitleVideoAddress> addressList = new List<SubtitleVideoAddress>();
                    int page = 1;
                    int maxPage = 1;
                    bool debug = true;
                    ImportFileList.Clear();
                    foreach (SubtitleTypeAndPages tp in typeAndPages)
                    {
                        page = tp.pages;
                        maxPage = 1;
                        do
                        {
                            if (page % 20 == 0)
                            {
                                Thread.Sleep(100);
                            }
                            else
                            {
                                Thread.Sleep(10);
                            }
                            addressList.Clear();
                            Stopwatch sw = new Stopwatch();
                            sw.Start();
                            ImportMessage = "处理：" + page + "/" + maxPage;
                            string url = string.Format(listAddress, tp.type, page);
                            string log = "处理：" + page + "/" + maxPage + "\t" + url;
                            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                            string content = httpClient
                                .GetStringAsync(url)
                                .GetAwaiter()
                                .GetResult();
                            doc.LoadHtml(content);
                            HtmlNodeCollection aTagList = doc.DocumentNode.SelectNodes(
                                "//a[contains(@class, '_5f002f3b72dfbde7079b2fee61053c2b91b270ac-vodlist__thumb lazyload')]"
                            );
                            HtmlNode numTag = doc.DocumentNode.SelectNodes(
                                "//span[contains(@class, 'num')]"
                            )[0];
                            maxPage = int.Parse(numTag.InnerHtml.Split("/")[1]);
                            foreach (HtmlNode a in aTagList)
                            {
                                string href = a.GetAttributeValue("href", "");
                                string address = "https://www.qdairep.com" + href;
                                string vid = href.Replace("/filmview/", "").Replace(".html", "");
                                string title = a.GetAttributeValue("title", "");
                                if (!title.Contains("粤语"))
                                {
                                    string word = a.GetAttributeValue("title", "");
                                    string image = a.GetAttributeValue("data-original", "");
                                    SubtitleVideoAddress vaddress = new SubtitleVideoAddress();
                                    vaddress.vid = vid;
                                    vaddress.title = title;
                                    vaddress.vtype = 0;
                                    vaddress.mtype = 2;
                                    vaddress.image = image;
                                    addressList.Add(vaddress);
                                    ImportFileList.Add(
                                        new SubtitleImport() { FileName = title + "\t" + address }
                                    );
                                }
                            }
                            page++;
                            if (addressList.Count > 0)
                            {
                                //importService.insertAddress(addressList);
                                List<string> lines = new List<string>();
                                foreach (SubtitleVideoAddress va in addressList)
                                {
                                    lines.Add(JsonConvert.SerializeObject(va));
                                }
                                File.AppendAllLines("d:/address.json", lines);
                            }
                            sw.Stop();
                            log +=
                                "已成功导入["
                                + addressList.Count
                                + "条数据] 耗时 "
                                + sw.ElapsedMilliseconds
                                + " 毫秒";
                            Log.Information(log);
                        } while (maxPage >= page || !debug);
                    }
                })
            );
        public ICommand ImportSubtitleCommand =>
            _ImportSubtitleCommand
            ?? (
                _ImportSubtitleCommand = new RelayCommand<object>(o =>
                {
                    System.Windows.Controls.ListBox listBox = (System.Windows.Controls.ListBox)o;
                    string[] infos = ImportFolder.Split("\\");

                    Dictionary<string, SubtitleName> nameMap = importService.initName(
                        ImportFolder,
                        ImportFileList,
                        ImportAddress
                    );
                    List<SubtitleImport> imports = new List<SubtitleImport>();
                    for (int i = 0; i < ImportFileList.Count; i++)
                    {
                        SubtitleImport si = ImportFileList[i];
                        string path = ImportFileList[i].FileName;
                        var importResult = importService.importSubtitle(
                            ImportFolder,
                            si,
                            ImportAddress
                        );
                        int count = importResult.count;
                        SubtitleName name = importResult.name;
                        if (count > 0)
                        {
                            doneCount++;
                            si.Count = count;
                            si.Desc = AppConstants.ImportDone;
                            var content = new NotificationContent()
                            {
                                Title = si.FileName,
                                Type = NotificationType.Success,
                                Message = "已成功导入文件" + "[" + count + "条数据]",
                            };
                            AppManager.Instance.NotificationManager.Show(content);
                        }
                        else
                        {
                            var content = new NotificationContent()
                            {
                                Title = si.FileName,
                                Type = NotificationType.Error,
                                Message = "导入数据失败",
                            };
                            si.Desc = "失败";
                            AppManager.Instance.NotificationManager.Show(content);
                            return;
                        }
                        imports.Add(si);
                    }
                    importService.updateCount(nameMap);
                    doneCount = 0;
                    foreach (var nm in nameMap.Values)
                    {
                        doneCount += nm.count;
                    }
                    //System.Windows.MessageBox.Show("已成功导入[" + doneCount + "条数据]");
                    //ImportSubtitleEnabled = false;
                    //ImportFileList.Clear();
                    //foreach(var si in imports)
                    //{
                    //    ImportFileList.Add(si);
                    //}
                    ImportFileList.Clear();
                    ImportFolder = "";
                    ImportAddress = "";
                    ImportMessage = "";
                })
            );
        public ICommand ImportVideoInfoCommand =>
            _ImportVideoInfoCommand
            ?? (
                _ImportVideoInfoCommand = new RelayCommand<object>(o =>
                {
                    string[] lines = File.ReadAllLines("./videoInfo.json");
                    List<SubtitleVideoAddress> addresses = new List<SubtitleVideoAddress>();
                    int count = 0;
                    foreach (string line in lines)
                    {
                        SubtitleVideoAddress va =
                            JsonConvert.DeserializeObject<SubtitleVideoAddress>(line);
                        addresses.Add(va);
                        count++;
                        if (count >= 500)
                        {
                            importService.insertAddress(addresses);
                            addresses.Clear();
                            count = 0;
                        }
                    }
                })
            );

        public ICommand ImportOpenFolderCommand =>
            _ImportOpenFolderCommand
            ?? (
                _ImportOpenFolderCommand = new RelayCommand<object>(o =>
                {
                    ImportFileList.Clear();
                    var openit = importService.open(BatchImportChecked);
                    if (openit.folder == null)
                    {
                        return;
                    }
                    ImportFolder = openit.folder;
                    if (openit.files.Count > 0)
                    {
                        foreach (string file in openit.files)
                        {
                            SubtitleImport si = new SubtitleImport() { FileName = file };
                            ImportFileList.Add(si);
                        }
                        ImportMessage = "任务数量：" + ImportFileList.Count;
                        doneCount = 0;
                        checkFiles();
                    }
                })
            );

        private void checkFiles()
        {
            string pattern =
                "^[\\|\\dA-Za-z,\\*#\\./\"\\\\#%\\^&!@~★：·、。\\)\\(\\$\\+\\?\\[\\]=\\{\\}!`~\\- （）【】]+$";
            for (int i = 0; i < ImportFileList.Count; i++)
            {
                SubtitleImport si = ImportFileList[i];
                FileInfo fileInfo = new FileInfo(ImportFolder + "\\" + si.FileName);
                List<Subtitle> list = SubtitleUtils.ReadSubtitle(fileInfo);
                Log.Information("修改" + fileInfo.FullName);
                StringBuilder sb = new StringBuilder();
                int number = 0;
                List<vo.Subtitle> subtitles = new List<Subtitle>();
                foreach (Subtitle sub in list)
                {
                    if (sub.Text != null && sub.Text.Length > 0)
                    {
                        Match match = Regex.Match(sub.Text, pattern);
                        if (!match.Success)
                        {
                            //sub.Number = number++;
                            //sb.Append(sub.ToString()).AppendLine();
                            subtitles.Add(sub);
                        }
                        else
                        {
                            Serilog.Log.Information("忽略 " + sub.Text + " [" + si.FileName + "]");
                        }
                    }
                }
                Subtitle current = null;
                try
                {
                    current = subtitles[0];
                }
                catch (Exception ex)
                {
                    si.Desc = "异常：" + ex.Message;
                    return;
                }
                list.Clear();
                foreach (Subtitle sub in subtitles.Skip(1))
                {
                    if (sub.Text.Equals(current.Text))
                    {
                        current.EndTime = sub.EndTime;
                    }
                    else
                    {
                        list.Add(current);
                        current = sub;
                    }
                }
                list.Add(subtitles[subtitles.Count - 1]);
                foreach (Subtitle sub in list)
                {
                    if (sub.Text != null && sub.Text.Length > 0)
                    {
                        sub.Number = number++;
                        sb.Append(sub.ToString()).AppendLine();
                    }
                }
                si.Count = list.Count;
                File.WriteAllText(fileInfo.FullName, sb.ToString());
            }
            ImportSubtitleEnabled = true;
        }

        public ICommand ChangeVideoTypeCommand =>
            _ChangeVideoTypeCommand
            ?? (
                _ChangeVideoTypeCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;

                    VideoType = (VideoType)o;
                    ImportAddress = "";
                    ImportFileList.Clear();
                    ImportFolder = "";
                    ImportSubtitleEnabled = false;

                    if (VideoType == VideoType.TV)
                    {
                        importService = new SubtitleImportTvService();
                        BatchImportVisibility = Visibility.Visible;
                    }
                    else if (VideoType == VideoType.Movie)
                    {
                        importService = new SubtitleImportMovieService();
                        BatchImportVisibility = Visibility.Hidden;
                    }
                })
            );

        public ICommand SubtitleDoubleClickCommand =>
            _SubtitleDoubleClickCommand
            ?? (
                _SubtitleDoubleClickCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];
                    SearchSubtitle4UI vo = (SearchSubtitle4UI)controlArray[4];
                    searchNameComboBox.Text = vo.name;
                    AddCurrentSearchName(vo.name);
                })
            );
        public ICommand SubtitleClickCommand =>
            _SubtitleClickCommand
            ?? (
                _SubtitleClickCommand = new RelayCommand<object>(o =>
                {
                    try
                    {
                        VideoTipss.Clear();

                        if (o == null)
                            return;
                        else
                        {
                            SearchSubtitle4UI vo = (SearchSubtitle4UI)o;
                            AllSubtitles.Clear();
                            if (searchSubtitle)
                            {
                                //选中点击那一行的第一列的值，索引值必须是0，而且无论点这一行的第几列，选中的都是这一行第一列的值 ，如果想获取这一行除第一列外的值，则用subitems获取，[]中为索引，从1开始。
                                string sName = vo.name;
                                string sChapter = vo.chapter;
                                string sType = vo.type;
                                string sNameId = vo.numb;
                                string sStart = vo.start;
                                string sEnd = vo.end;
                                string sText = vo.text;
                                string desc =
                                    sName
                                    + "\t集数:"
                                    + sChapter
                                    + "\t类型:"
                                    + sType
                                    + "\t编号:"
                                    + sNameId
                                    + "\t开始 "
                                    + sStart
                                    + "\t结束 "
                                    + sEnd
                                    + "\t"
                                    + sText;
                                try
                                {
                                    System.Windows.Clipboard.SetDataObject(desc, true);
                                }
                                catch { }
                                string[] numInfos = sNameId.Split("/");
                                int nameId = int.Parse(numInfos[0]);
                                int numb = int.Parse(numInfos[1]);
                                var response = client.Search<SearchSubtitle>(s =>
                                    s.Index(SUBTITLE_INDEX)
                                        .From(0)
                                        .Size(10000)
                                        .Sort(s =>
                                            s.Field(
                                                f => f.start,
                                                f =>
                                                    f.Order(
                                                        Elastic.Clients.Elasticsearch.SortOrder.Asc
                                                    )
                                            )
                                        )
                                        .Query(q =>
                                            q.Bool(b =>
                                                b.Must(
                                                    m => m.Term(t => t.nameId, nameId),
                                                    m =>
                                                        m.Term(
                                                            t => t.chapter,
                                                            sChapter.Split("/")[0]
                                                        )
                                                )
                                            )
                                        )
                                );

                                if (response.IsValidResponse)
                                {
                                    IReadOnlyCollection<SearchSubtitle> documents =
                                        response.Documents;
                                    Dictionary<int, int> nameDict = new Dictionary<int, int>();
                                    StringBuilder sb = new StringBuilder();
                                    int subtitleIndex = 0;
                                    int gotoline = 0;
                                    foreach (SearchSubtitle sub in documents)
                                    {
                                        SearchSubtitle4UI vo1 = new SearchSubtitle4UI()
                                        {
                                            start = sub.start.Trim(),
                                            text = sub.text,
                                        };
                                        if (sub.numb == numb)
                                        {
                                            gotoline = subtitleIndex;
                                        }

                                        subtitleIndex++;
                                        AllSubtitles.Add(vo1);
                                    }
                                    AllSubtitleSelected = AllSubtitles[gotoline];
                                }
                            }
                            else
                            {
                                int nameId = int.Parse(vo.numb);
                                CountRequestDescriptor<SearchSubtitle> descriptor =
                                    new CountRequestDescriptor<SearchSubtitle>();
                                descriptor
                                    .Indices(SUBTITLE_INDEX)
                                    .Query(s => s.Term(t => t.nameId, nameId));
                                var response = client.Search<SearchSubtitle>(s =>
                                    s.Index(SUBTITLE_INDEX)
                                        .From(0)
                                        .Size(SIZE)
                                        .Sort(s =>
                                            s.Field(
                                                f => f.start,
                                                f =>
                                                    f.Order(
                                                        Elastic.Clients.Elasticsearch.SortOrder.Asc
                                                    )
                                            )
                                        )
                                        .Query(s => s.Term(t => t.nameId, nameId))
                                );

                                if (response.IsValidResponse)
                                {
                                    IReadOnlyCollection<SearchSubtitle> documents =
                                        response.Documents;

                                    //建议用封装的方法Add
                                    foreach (SearchSubtitle sub in documents)
                                    {
                                        SearchSubtitle4UI vo1 = new SearchSubtitle4UI()
                                        {
                                            start = sub.start.Trim(),
                                            text = sub.text,
                                        };
                                        AllSubtitles.Add(vo1);
                                    }
                                }
                            }
                            Elastic.Clients.Elasticsearch.SearchResponse<SubtitleVideoAddress> responseAddress =
                                client.Search<SubtitleVideoAddress>(s =>
                                    s.Index(ADDRESS_INDEX)
                                        .From(0)
                                        .Size(AddressRows * AddressCols)
                                        .Query(q =>
                                            q.Match(ma => ma.Field(f => f.title).Query(vo.name))
                                        )
                                );
                            if (responseAddress.IsValidResponse)
                            {
                                IReadOnlyCollection<SubtitleVideoAddress> addressDocuments =
                                    responseAddress.Documents;

                                VideoTipss.Clear();
                                foreach (SubtitleVideoAddress add in addressDocuments)
                                {
                                    string title = add.mtype == 1 ? "🎞" + add.title : add.title;
                                    string xurl = null;
                                    string sType = vo.type;
                                    string sChapter = vo.chapter;
                                    int type = sType.Equals("电影") ? 1 : 2;
                                    string[] chapterInfos = sChapter.Split("/");
                                    int currentChapter = int.Parse(chapterInfos[0]);
                                    if (add.vtype == 1)
                                    {
                                        //金牌影视
                                        if (
                                            add.mtype == type
                                            && searchSubtitle
                                            && add.cids != null
                                            && add.cids.Length > 0
                                            && add.cids.Split(",").Length
                                                == int.Parse(chapterInfos[1])
                                        )
                                        {
                                            xurl =
                                                $"https://www.chrqj.com/vod/play/{add.vid}/sid/{add.cids.Split(",")[currentChapter - 1]}";
                                        }
                                        else
                                        {
                                            xurl = $"https://www.chrqj.com/detail/{add.vid}";
                                        }
                                    }
                                    else
                                    {
                                        if (add.mtype == type && searchSubtitle)
                                        {
                                            xurl =
                                                $"https://www.qdairep.com/filmplay/{add.vid}-0-{currentChapter - 1}.html";
                                        }
                                        else
                                        {
                                            xurl =
                                                $"https://www.qdairep.com/filmview/{add.vid}.html";
                                        }
                                    }

                                    SubtitleVideoTips tips = new SubtitleVideoTips
                                    {
                                        url = xurl,
                                        desc = add.desc,
                                        image = add.image,
                                        vid = add.vid,
                                        vtype = add.vtype,
                                        mtype = add.mtype,
                                        title = title,
                                    };
                                    VideoTipss.Add(tips);
                                }
                            }
                        }
                    }
                    catch { }
                })
            );

        public ICommand SearchSubtitleCommand =>
            _SearchSubtitleCommand
            ?? (
                _SearchSubtitleCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];

                    StartHeader = START_TIME_TEXT;
                    EndHeader = END_TIME_TEXT;
                    SubtitleHeader = SUBTITLE_TEXT;

                    searchSubtitle = true;
                    int nameIdSize = 10;
                    SearchSubtitles.Clear();
                    Elastic.Clients.Elasticsearch.SearchResponse<SearchSubtitle> response = null;
                    List<FieldValue> searchNameIds = new List<FieldValue>();
                    if (OnlyOne)
                    {
                        nameIdSize = 1;
                    }
                    string _searchName = null;
                    if (searchNameComboBox != null && searchNameComboBox.SelectedItem != null)
                    {
                        _searchName = searchNameComboBox.SelectedItem.ToString().Trim();
                    }
                    string _search = null;
                    if (searchTextBox != null)
                    {
                        _search = searchTextBox.Text.Trim();
                    }
                    if (!string.IsNullOrEmpty(_searchName))
                    {
                        Elastic.Clients.Elasticsearch.SearchResponse<SubtitleName> nameResponse =
                            client.Search<SubtitleName>(s =>
                                s.Index(NAME_INDEX)
                                    .From(0)
                                    .Size(nameIdSize)
                                    .Query(q =>
                                        q.Match(ma => ma.Field(f => f.name).Query(_searchName))
                                    )
                            );
                        AddCurrentSearchName(_searchName);

                        if (nameResponse.IsValidResponse)
                        {
                            IReadOnlyCollection<SubtitleName> nameDocuments =
                                nameResponse.Documents;
                            foreach (SubtitleName name in nameDocuments)
                            {
                                //searchNameId = name.nameId;
                                searchNameIds.Add(name.nameId);
                                //break;
                            }
                        }
                    }
                    if (string.IsNullOrEmpty(_search))
                    {
                        Random random = new Random();
                        if (string.IsNullOrEmpty(_searchName))
                        {
                            searchNameIds.Add(Math.Abs(random.Next((int)nameCount)));
                        }
                        if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
                        {
                            response = client.Search<SearchSubtitle>(s =>
                                s.Index(SUBTITLE_INDEX)
                                    .From(0)
                                    .Size(SIZE)
                                    .Query(q =>
                                        q.Bool(b =>
                                            b.Should(sh =>
                                                sh.Terms(tms =>
                                                    tms.Field(ff => ff.nameId)
                                                        .Terms(new TermsQueryField(searchNameIds))
                                                )
                                            )
                                        )
                                    )
                            );
                        }
                        else
                        {
                            response = client.Search<SearchSubtitle>(s =>
                                s.Index(SUBTITLE_INDEX)
                                    .From(0)
                                    .Size(SIZE)
                                    .Query(q =>
                                        q.Bool(b =>
                                            b.Must(
                                                m =>
                                                    m.Bool(bb =>
                                                        bb.Should(sh =>
                                                            sh.Terms(tms =>
                                                                tms.Field(ff => ff.nameId)
                                                                    .Terms(
                                                                        new TermsQueryField(
                                                                            searchNameIds
                                                                        )
                                                                    )
                                                            )
                                                        )
                                                    ),
                                                m =>
                                                    m.FunctionScore(f =>
                                                        f.Functions(f1 =>
                                                            f1.RandomScore(rs => rs.Seed(null))
                                                        )
                                                    )
                                            )
                                        )
                                    )
                            );
                        }
                    }
                    else
                    {
                        if (searchNameIds.Count != 0)
                        {
                            response = client.Search<SearchSubtitle>(s =>
                                s.Index(SUBTITLE_INDEX)
                                    .From(0)
                                    .Size(SIZE)
                                    .Query(q =>
                                        q.Bool(b =>
                                            b.Must(
                                                m =>
                                                    m.Bool(bb =>
                                                        bb.Should(sh =>
                                                            sh.Terms(tms =>
                                                                tms.Field(ff => ff.nameId)
                                                                    .Terms(
                                                                        new TermsQueryField(
                                                                            searchNameIds
                                                                        )
                                                                    )
                                                            )
                                                        )
                                                    ),
                                                m =>
                                                    m.Match(ma =>
                                                        ma.Field(f => f.text).Query(_search)
                                                    )
                                            )
                                        )
                                    )
                            );
                        }
                        else
                        {
                            response = client.Search<SearchSubtitle>(s =>
                                s.Index(SUBTITLE_INDEX)
                                    .From(0)
                                    .Size(SIZE)
                                    .Query(q => q.Match(ma => ma.Field(f => f.text).Query(_search)))
                            );
                        }
                    }

                    if (response.IsValidResponse)
                    {
                        SearchCount = "结果数量：" + response.HitsMetadata.Total.Value;

                        IReadOnlyCollection<SearchSubtitle> documents = response.Documents;
                        Dictionary<int, int> nameDict = new Dictionary<int, int>();
                        foreach (SearchSubtitle sub in documents)
                        {
                            if (!nameDict.ContainsKey(sub.nameId))
                            {
                                nameDict.Add(sub.nameId, sub.nameId);
                            }
                        }
                        FieldValue[] fieldValues = new FieldValue[nameDict.Count];
                        int i = 0;
                        foreach (var nameId in nameDict.Keys)
                        {
                            fieldValues[i++] = nameId.ToString();
                        }
                        var responseCate = client.Search<SubtitleName>(s =>
                            s.Index(NAME_INDEX)
                                .From(0)
                                .Size(SIZE)
                                .Query(q =>
                                    q.Terms(
                                        new Elastic.Clients.Elasticsearch.QueryDsl.TermsQuery
                                        {
                                            Field =
                                                Elastic.Clients.Elasticsearch.Infer.Field<SubtitleName>(
                                                    d => d.nameId
                                                ),
                                            Terms = new TermsQueryField(fieldValues),
                                        }
                                    )
                                )
                        );
                        Dictionary<int, SubtitleName> nameDictory =
                            new Dictionary<int, SubtitleName>();

                        if (responseCate.IsValidResponse)
                        {
                            IReadOnlyCollection<SubtitleName> nameDocuments =
                                responseCate.Documents;
                            foreach (SubtitleName name in nameDocuments)
                            {
                                nameDictory.Add(name.nameId, name);
                            }
                        }
                        int index = 0;
                        foreach (SearchSubtitle sub in documents)
                        {
                            SubtitleName aname = nameDictory.ContainsKey(sub.nameId)
                                ? nameDictory[sub.nameId]
                                : null;
                            string sname = aname != null ? aname.name : "";
                            int chapterCount = aname != null ? aname.chapterCount : 1;
                            SearchSubtitle4UI vo = new SearchSubtitle4UI()
                            {
                                name = sname,
                                chapter = sub.chapter.ToString() + "/" + chapterCount,
                                type = aname != null ? aname.cateDesc : "",
                                numb = sub.nameId.ToString() + "/" + sub.numb.ToString(),
                                start = sub.start,
                                end = sub.end,
                                text = sub.text,
                            };

                            index++;
                            SearchSubtitles.Add(vo);
                        }
                    }
                })
            );
        public ICommand ConfigEsCommand =>
            _ConfigEsCommand
            ?? (
                _ConfigEsCommand = new RelayCommand<object>(o =>
                {
                    if (string.IsNullOrEmpty(AppConfig.Instance.EsAddress))
                    {
                        System.Windows.MessageBox.Show("请输入ES地址", "错误");
                        return;
                    }
                    if (string.IsNullOrEmpty(AppConfig.Instance.EsFingerprint))
                    {
                        System.Windows.MessageBox.Show("请输入ES指纹", "错误");
                        return;
                    }
                    if (string.IsNullOrEmpty(AppConfig.Instance.EsUserName))
                    {
                        System.Windows.MessageBox.Show("请输入ES用户名", "错误");
                        return;
                    }
                    if (string.IsNullOrEmpty(AppConfig.Instance.EsPassword))
                    {
                        System.Windows.MessageBox.Show("请输入ES密码", "错误");
                        return;
                    }
                    var settings = new ElasticsearchClientSettings(
                        new Uri(AppConfig.Instance.EsAddress)
                    )
                        .CertificateFingerprint(AppConfig.Instance.EsFingerprint)
                        .Authentication(
                            new BasicAuthentication(
                                AppConfig.Instance.EsUserName,
                                AppConfig.Instance.EsPassword
                            )
                        );

                    client = new ElasticsearchClient(settings);

                    var response = client.Search<object>(s =>
                        s.Index(SearchSubtitleCommands.SUBTITLE_INDEX).From(0).Size(100)
                    );
                    bool success = response.IsSuccess();
                    if (!success)
                    {
                        System.Windows.MessageBox.Show("不能正常连接ES，请检查输入信息", "错误");
                        return;
                    }
                    else
                    {
                        System.Windows.MessageBox.Show("配置成功，请重启服务才可正常使用", "错误");
                    }
                    AppConfig.Instance.Save();
                    MainWindowCommands.Instance.CloseDialogCommand.ExecuteIfCan();
                })
            );

        public ICommand OpenConfigEsCommand =>
            _OpenConfigEsCommand
            ?? (
                _OpenConfigEsCommand = new RelayCommand<object>(o =>
                {
                    MainWindowCommands.Instance.dialog = new CustomDialog(
                        MainWindow.Instance.MetroDialogOptions
                    )
                    {
                        Content = ConfigEsWindow.Instance,
                        Title = "设置ES",
                        Style = (Style)
                            System.Windows.Application.Current.Resources["CustomDialogStyle"], // 应用样式
                    };
                    MainWindow.Instance.ShowMetroDialogAsync(MainWindowCommands.Instance.dialog);
                })
            );
        public ICommand OpenDeleteSubtitleCommand =>
            _OpenDeleteSubtitleCommand
            ?? (
                _OpenDeleteSubtitleCommand = new RelayCommand<object>(o =>
                {
                    MainWindowCommands.Instance.dialog = new CustomDialog(
                        MainWindow.Instance.MetroDialogOptions
                    )
                    {
                        Content = DeleteSubtitleWindow.Instance,
                        Title = "删除字幕",
                        Style = (Style)
                            System.Windows.Application.Current.Resources["CustomDialogStyle"], // 应用样式
                    };
                    MainWindow.Instance.ShowMetroDialogAsync(MainWindowCommands.Instance.dialog);
                })
            );
        public ICommand DeleteSubtitleCommand =>
            _DeleteSubtitleCommand
            ?? (
                _DeleteSubtitleCommand = new RelayCommand<object>(o =>
                {
                    int nameId = int.Parse(DeleteNameId);
                    if (nameId == 0)
                    {
                        var content = new NotificationContent()
                        {
                            Title = "NameId不合法",
                            Type = NotificationType.Error,
                            Message = "请输入非零的nameId ，" + DeleteNameId,
                        };
                        AppManager.Instance.NotificationManager.Show(content);
                        return;
                    }
                    var deleteQuery = new Elastic.Clients.Elasticsearch.DeleteByQueryRequest(
                        SUBTITLE_INDEX
                    )
                    {
                        Query = new Elastic.Clients.Elasticsearch.QueryDsl.TermQuery(
                            new Elastic.Clients.Elasticsearch.Field("nameId")
                        )
                        {
                            Value = nameId,
                        },
                    };
                    Elastic.Clients.Elasticsearch.DeleteByQueryResponse deleteByQueryResponse =
                        client.DeleteByQuery(deleteQuery);
                    string log = "";
                    if (deleteByQueryResponse.IsValidResponse)
                    {
                        log = $"已删除[nameId={nameId}]{deleteByQueryResponse.Deleted.Value}条数据";
                    }
                    if (DeleteAllNameId)
                    {
                        deleteQuery = new Elastic.Clients.Elasticsearch.DeleteByQueryRequest(
                            NAME_INDEX
                        )
                        {
                            Query = new Elastic.Clients.Elasticsearch.QueryDsl.TermQuery(
                                new Elastic.Clients.Elasticsearch.Field("nameId")
                            )
                            {
                                Value = nameId,
                            },
                        };
                        deleteByQueryResponse = client.DeleteByQuery(deleteQuery);
                        if (deleteByQueryResponse.IsValidResponse)
                        {
                            log += $"和{deleteByQueryResponse.Deleted.Value}条剧集数据";
                        }
                    }
                    else
                    {
                        Elastic.Clients.Elasticsearch.QueryDsl.TermQuery termQuery =
                            new Elastic.Clients.Elasticsearch.QueryDsl.TermQuery(
                                new Elastic.Clients.Elasticsearch.Field("nameId")
                            )
                            {
                                Value = nameId,
                            };
                        Elastic.Clients.Elasticsearch.SearchResponse<SubtitleName> searchResponse =
                            client.Search<SubtitleName>(s =>
                                s.Index(NAME_INDEX).From(0).Size(1).Query(q => q.Term(termQuery))
                            );
                        if (searchResponse.IsValidResponse)
                        {
                            IReadOnlyCollection<SubtitleName> documents = searchResponse.Documents;
                            if (documents.Count == 1)
                            {
                                SubtitleName nm = documents.First();
                                nm.count = 0;
                                Elastic.Clients.Elasticsearch.IndexRequest<SubtitleName> ir =
                                    new Elastic.Clients.Elasticsearch.IndexRequest<SubtitleName>(
                                        nm,
                                        NAME_INDEX,
                                        nm.nameId
                                    );
                                var responseIndex = client.Index(ir);
                            }
                        }
                    }
                    var content1 = new NotificationContent()
                    {
                        Title = "删除结果",
                        Type = NotificationType.Success,
                        Message = log,
                    };
                    AppManager.Instance.NotificationManager.Show(content1);
                    DeleteSubtitleWindow wnd = DeleteSubtitleWindow.Instance;
                    MainWindowCommands.Instance.CloseDialogCommand.ExecuteIfCan();
                })
            );

        public ICommand StatisticSubtitleCommand =>
            _StatisticSubtitleCommand
            ?? (
                _StatisticSubtitleCommand = new RelayCommand<object>(o =>
                {
                    var aggreResponse = client.Search<SearchSubtitle>(s =>
                        s.Index(SUBTITLE_INDEX)
                            .Size(0)
                            .Aggregations(a =>
                                a.Terms("nameId", t => t.Field(f => f.nameId).Size(10000))
                            )
                    );
                    Dictionary<int, int> countMap = new Dictionary<int, int>();
                    if (aggreResponse.IsValidResponse)
                    {
                        long cnt = aggreResponse.Hits.Count;

                        IEnumerable<Elastic.Clients.Elasticsearch.Aggregations.IAggregate> values =
                            aggreResponse.Aggregations.Values;
                        foreach (
                            Elastic.Clients.Elasticsearch.Aggregations.IAggregate agg in values
                        )
                        {
                            LongTermsAggregate termsAggregate = (LongTermsAggregate)agg;
                            IReadOnlyCollection<LongTermsBucket> buckets = termsAggregate.Buckets;
                            foreach (LongTermsBucket bucket in buckets)
                            {
                                countMap.Add((int)bucket.Key, (int)bucket.DocCount);
                            }
                        }
                    }

                    var response = client.Search<SubtitleName>(s =>
                        s.Index(NAME_INDEX)
                            .From(0)
                            .Size(10000)
                            .Sort(s =>
                                s.Field(
                                    "nameId",
                                    f => f.Order(Elastic.Clients.Elasticsearch.SortOrder.Desc)
                                )
                            )
                    );
                    StringBuilder sb = new StringBuilder();
                    if (response.IsValidResponse)
                    {
                        IReadOnlyCollection<SubtitleName> documents = response.Documents;
                        if (response.HitsMetadata.Total.Value == 0)
                        {
                            StatisticProjectCount = "剧集数量: 0";
                            StatisticSubtitleCount = "字幕数量: 0";
                        }
                        else
                        {
                            StatisticProjectCount =
                                "剧集数量: " + response.HitsMetadata.Total.Value;
                            int i = 0;
                            int sumCount = 0;
                            foreach (var document in documents)
                            {
                                int count = 0;
                                if (countMap.ContainsKey(document.nameId))
                                {
                                    count = countMap[document.nameId];
                                }
                                sumCount += document.count;
                                SearchSubtitle v = new SearchSubtitle()
                                {
                                    nameId = document.nameId,
                                    text = document.name,
                                    numb = document.count,
                                };
                                StatisticSubtitleList.Add(v);
                                if (count != document.count)
                                {
                                    sb.Append(
                                            document.nameId
                                                + " name中count = "
                                                + document.count.ToString()
                                                + ",subtitle中count = "
                                                + count
                                        )
                                        .Append("\n");
                                }

                                i++;
                            }
                            if (sb.Length > 0)
                            {
                                System.Windows.MessageBox.Show("数据量不一致", sb.ToString());
                            }
                            StatisticSubtitleCount = "字幕索引数据量: " + sumCount.ToString();
                        }
                    }

                    MainWindowCommands.Instance.dialog = new CustomDialog(
                        MainWindow.Instance.MetroDialogOptions
                    )
                    {
                        Content = StatisticSubtitleWindow.Instance,
                        Title = "字幕统计",
                        Style = (Style)
                            System.Windows.Application.Current.Resources["CustomDialogStyle"], // 应用样式
                    };
                    MainWindow.Instance.ShowMetroDialogAsync(MainWindowCommands.Instance.dialog);
                })
            );

        public ICommand OpenImportSubtitleCommand =>
            _OpenImportSubtitleCommand
            ?? (
                _OpenImportSubtitleCommand = new RelayCommand<object>(o =>
                {
                    MainWindowCommands.Instance.dialog = new CustomDialog(
                        MainWindow.Instance.MetroDialogOptions
                    )
                    {
                        Content = ImportSubtitleWindow.Instance,
                        Title = "导入字幕",
                        Style = (Style)
                            System.Windows.Application.Current.Resources["CustomDialogStyle"], // 应用样式
                    };
                    MainWindow.Instance.ShowMetroDialogAsync(MainWindowCommands.Instance.dialog);
                })
            );

        public ICommand SearchNameCommand =>
            _SearchNameCommand
            ?? (
                _SearchNameCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];

                    StartHeader = CREATE_TIME_TEXT;
                    EndHeader = NO_NAME_TEXT;
                    SubtitleHeader = SUBTITLE_COUNT_TEXT;
                    searchSubtitle = false;
                    string keyword = "";
                    Elastic.Clients.Elasticsearch.SearchResponse<SubtitleName> response = null;
                    string _name = nameComboBox.SelectedItem.ToString();
                    if (string.IsNullOrEmpty(_name))
                    {
                        var randomSeed = DateTime.Now.Ticks.ToString();
                        if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
                        {
                            response = client.Search<SubtitleName>(s =>
                                s.Index(NAME_INDEX)
                                    .From(0)
                                    .Size(SIZE)
                                    .Sort(s =>
                                        s.Field(
                                            f => f.nameId,
                                            f =>
                                                f.Order(
                                                    Elastic.Clients.Elasticsearch.SortOrder.Desc
                                                )
                                        )
                                    )
                            );
                        }
                        else
                        {
                            response = client.Search<SubtitleName>(s =>
                                s.Index(NAME_INDEX)
                                    .From(0)
                                    .Size(SIZE)
                                    .Query(q =>
                                        q.FunctionScore(fs =>
                                            fs.Query(q => q.MatchAll())
                                                .Functions(f => f.RandomScore(rs => rs.Seed(null)))
                                                .BoostMode(
                                                    Elastic
                                                        .Clients
                                                        .Elasticsearch
                                                        .QueryDsl
                                                        .FunctionBoostMode
                                                        .Replace
                                                )
                                        )
                                    )
                            );
                        }
                    }
                    else
                    {
                        AddCurrentName(_name);
                        response = client.Search<SubtitleName>(s =>
                            s.Index(NAME_INDEX)
                                .From(0)
                                .Size(SIZE)
                                .Query(q => q.Match(ma => ma.Field(f => f.name).Query(_name)))
                        );
                    }

                    if (response.IsValidResponse)
                    {
                        SearchCount = "结果数量：" + response.HitsMetadata.Total.Value;
                        IReadOnlyCollection<SubtitleName> documents = response.Documents;
                        SearchSubtitles.Clear();
                        int index = 0;
                        foreach (SubtitleName name in documents)
                        {
                            keyword += name.name + ",";
                            SearchSubtitle4UI vo = new SearchSubtitle4UI()
                            {
                                name = name.name,
                                chapter = name.chapterCount.ToString(),
                                type = name.cateDesc,
                                numb = name.nameId.ToString(),
                                start = name.createTime,
                                end = "",
                                text = name.count.ToString(),
                            };
                            index++;
                            SearchSubtitles.Add(vo);
                        }
                    }
                })
            );
        public ICommand NameToSearchNameCommand =>
            _NameToSearchNameCommand
            ?? (
                _NameToSearchNameCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];
                    AddCurrentSearchName(nameComboBox.SelectedItem.ToString());
                    object[] objects = new object[]
                    {
                        searchNameComboBox,
                        searchTextBox,
                        nameComboBox,
                        videoComboBox,
                    };
                    searchNameComboBox.SelectedIndex = 0;
                    SearchSubtitleCommand.ExecuteIfCan(objects);
                })
            );

        public ICommand SearchNameToNameCommand =>
            _SearchNameToNameCommand
            ?? (
                _SearchNameToNameCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];
                    AddCurrentName(searchNameComboBox.SelectedItem.ToString());
                    object[] objects = new object[]
                    {
                        searchNameComboBox,
                        searchTextBox,
                        nameComboBox,
                        videoComboBox,
                    };
                    nameComboBox.SelectedIndex = 0;
                    SearchNameCommand.ExecuteIfCan(objects);
                })
            );
        public ICommand VideoToSearchNameCommand =>
            _VideoToSearchNameCommand
            ?? (
                _VideoToSearchNameCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];
                    string video = string.Empty;
                    if (
                        videoComboBox.SelectedItem == null
                        || string.IsNullOrEmpty(videoComboBox.SelectedItem.ToString())
                    )
                    {
                        if (string.IsNullOrEmpty(videoComboBox.Text))
                        {
                            return;
                        }
                        else
                        {
                            video = videoComboBox.Text;
                        }
                        return;
                    }
                    else
                    {
                        video = videoComboBox.SelectedItem.ToString();
                    }
                    AddCurrentSearchName(video);
                    object[] objects = new object[]
                    {
                        searchNameComboBox,
                        searchTextBox,
                        nameComboBox,
                        videoComboBox,
                    };
                    searchNameComboBox.SelectedIndex = 0;
                    SearchSubtitleCommand.ExecuteIfCan(objects);
                })
            );

        public ICommand VideoToNameCommand =>
            _VideoToNameCommand
            ?? (
                _VideoToNameCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];
                    string video = string.Empty;
                    if (
                        videoComboBox.SelectedItem == null
                        || string.IsNullOrEmpty(videoComboBox.SelectedItem.ToString())
                    )
                    {
                        if (string.IsNullOrEmpty(videoComboBox.Text))
                        {
                            return;
                        }
                        else
                        {
                            video = videoComboBox.Text;
                        }
                        return;
                    }
                    else
                    {
                        video = videoComboBox.SelectedItem.ToString();
                    }
                    AddCurrentName(video);
                    object[] objects = new object[]
                    {
                        searchNameComboBox,
                        searchTextBox,
                        nameComboBox,
                        videoComboBox,
                    };
                    nameComboBox.SelectedIndex = 0;
                    SearchNameCommand.ExecuteIfCan(objects);
                })
            );

        public ICommand NameToVideoCommand =>
            _NameToVideoCommand
            ?? (
                _NameToVideoCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];
                    AddCurrentVideo(nameComboBox.SelectedItem.ToString());
                    object[] objects = new object[]
                    {
                        searchNameComboBox,
                        searchTextBox,
                        nameComboBox,
                        videoComboBox,
                    };
                    videoComboBox.SelectedIndex = 0;
                    SearchVideoCommand.ExecuteIfCan(objects);
                })
            );

        public ICommand SearchNameToVideoCommand =>
            _SearchNameToVideoCommand
            ?? (
                _SearchNameToVideoCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];
                    AddCurrentVideo(searchNameComboBox.SelectedItem.ToString());
                    object[] objects = new object[]
                    {
                        searchNameComboBox,
                        searchTextBox,
                        nameComboBox,
                        videoComboBox,
                    };
                    videoComboBox.SelectedIndex = 0;
                    SearchVideoCommand.ExecuteIfCan(objects);
                })
            );

        public ICommand SearchVideoCommand =>
            _SearchVideoCommand
            ?? (
                _SearchVideoCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                        return;
                    var controlArray = (object[])o;
                    ComboBox searchNameComboBox = (ComboBox)controlArray[0];
                    TextBox searchTextBox = (TextBox)controlArray[1];
                    ComboBox nameComboBox = (ComboBox)controlArray[2];
                    ComboBox videoComboBox = (ComboBox)controlArray[3];
                    string video = string.Empty;
                    if (
                        videoComboBox.SelectedItem == null
                        || string.IsNullOrEmpty(videoComboBox.SelectedItem.ToString())
                    )
                    {
                        if (string.IsNullOrEmpty(videoComboBox.Text))
                        {
                            return;
                        }
                        else
                        {
                            video = videoComboBox.Text;
                        }
                        return;
                    }
                    else
                    {
                        video = videoComboBox.SelectedItem.ToString();
                    }

                    AddCurrentVideo(video);
                    Elastic.Clients.Elasticsearch.SearchResponse<SubtitleVideoAddress> responseAddress =
                        client.Search<SubtitleVideoAddress>(s =>
                            s.Index(ADDRESS_INDEX)
                                .From(0)
                                .Size(8 * 8)
                                .Query(q => q.Match(ma => ma.Field(f => f.title).Query(video)))
                        );
                    if (responseAddress.IsValidResponse)
                    {
                        VideoTipss.Clear();
                        IReadOnlyCollection<SubtitleVideoAddress> addressDocuments =
                            responseAddress.Documents;

                        foreach (SubtitleVideoAddress add in addressDocuments)
                        {
                            string xurl = null;
                            if (add.vtype == 1)
                            {
                                //金牌影视
                                xurl = $"https://www.chrqj.com/detail/{add.vid}";
                            }
                            else
                            {
                                xurl = $"https://www.qdairep.com/filmview/{add.vid}.html";
                            }
                            SubtitleVideoTips tips = new SubtitleVideoTips
                            {
                                url = xurl,
                                desc = add.desc,
                                image = add.image,
                                vid = add.vid,
                                vtype = add.vtype,
                                mtype = add.mtype,
                                title = add.title,
                            };
                            VideoTipss.Add(tips);
                        }
                    }
                })
            );

        public void AddCurrentSearchName(string searchName)
        {
            if (searchName != null && searchName.Trim().Length > 0)
            {
                if (SearchNameHistorys.Contains(searchName))
                {
                    SearchNameHistorys.Remove(searchName);
                }
                SearchNameHistorys.Insert(0, searchName);
                if (SearchNameHistorys.Count > AppConstants.MaxHistoryCount)
                {
                    for (int i = AppConstants.MaxHistoryCount; i < SearchNameHistorys.Count; i++)
                    {
                        AppConfig.Instance.SearchNameHistorys.RemoveAt(
                            AppConstants.MaxHistoryCount
                        );
                    }
                }
                AppConfig.Instance.SearchNameHistorys = SearchNameHistorys;
                AppConfig.Instance.Save();
                SearchSubtitlePage.Instance.GetSearchNameComboBox().SelectedIndex = 0;
                LastSearchName = SearchNameHistorys[0];
            }
        }

        public void AddCurrentName(string name)
        {
            if (name != null && name.Trim().Length > 0)
            {
                if (NameHistorys.Contains(name))
                {
                    NameHistorys.Remove(name);
                }
                NameHistorys.Insert(0, name);
                if (NameHistorys.Count > AppConstants.MaxHistoryCount)
                {
                    for (int i = AppConstants.MaxHistoryCount; i < NameHistorys.Count; i++)
                    {
                        NameHistorys.RemoveAt(AppConstants.MaxHistoryCount);
                    }
                }
                AppConfig.Instance.NameHistorys = NameHistorys;
                AppConfig.Instance.Save();
                SearchSubtitlePage.Instance.GetNameComboBox().SelectedIndex = 0;
                LastName = NameHistorys[0];
            }
        }

        public void AddCurrentVideo(string video)
        {
            if (video != null && video.Trim().Length > 0)
            {
                if (VideoHistorys.Contains(video))
                {
                    VideoHistorys.Remove(video);
                }
                VideoHistorys.Insert(0, video);
                if (VideoHistorys.Count > AppConstants.MaxHistoryCount)
                {
                    for (int i = AppConstants.MaxHistoryCount; i < VideoHistorys.Count; i++)
                    {
                        VideoHistorys.RemoveAt(AppConstants.MaxHistoryCount);
                    }
                }
                AppConfig.Instance.VideoHistorys = VideoHistorys;
                AppConfig.Instance.Save();
                SearchSubtitlePage.Instance.GetVideoComboBox().SelectedIndex = 0;
                LastVideo = VideoHistorys[0];
            }
        }

        public string LastVideo = string.Empty;
        public string LastName = string.Empty;
        public string LastSearchName = string.Empty;
        public string LastSearch = string.Empty;
        private bool _OnlyOne;

        public bool OnlyOne
        {
            get => _OnlyOne;
            set => SetProperty(ref _OnlyOne, value);
        }

        private string _SubtitleCount;

        public string SubtitleCount
        {
            get => _SubtitleCount;
            set => SetProperty(ref _SubtitleCount, value);
        }

        private string _StartHeader = START_TIME_TEXT;

        public string StartHeader
        {
            get => _StartHeader;
            set => SetProperty(ref _StartHeader, value);
        }

        private string _EndHeader = END_TIME_TEXT;

        public string EndHeader
        {
            get => _EndHeader;
            set => SetProperty(ref _EndHeader, value);
        }

        private string _SubtitleHeader = SUBTITLE_TEXT;

        public string SubtitleHeader
        {
            get => _SubtitleHeader;
            set => SetProperty(ref _SubtitleHeader, value);
        }

        private string _SearchCount;

        public string SearchCount
        {
            get => _SearchCount;
            set => SetProperty(ref _SearchCount, value);
        }
        private ObservableCollection<SearchSubtitle4UI> _SearchSubtitles =
            new ObservableCollection<SearchSubtitle4UI>();

        public ObservableCollection<SearchSubtitle4UI> SearchSubtitles
        {
            get => _SearchSubtitles;
            set => SetProperty(ref _SearchSubtitles, value);
        }

        private ObservableCollection<SubtitleVideoTips> _VideoTipss =
            new ObservableCollection<SubtitleVideoTips>();

        public ObservableCollection<SubtitleVideoTips> VideoTipss
        {
            get => _VideoTipss;
            set => SetProperty(ref _VideoTipss, value);
        }
        private ObservableCollection<SearchSubtitle4UI> _AllSubtitles =
            new ObservableCollection<SearchSubtitle4UI>();

        public ObservableCollection<SearchSubtitle4UI> AllSubtitles
        {
            get => _AllSubtitles;
            set => SetProperty(ref _AllSubtitles, value);
        }

        private bool _DeleteAllNameId;

        public bool DeleteAllNameId
        {
            get => _DeleteAllNameId;
            set => SetProperty(ref _DeleteAllNameId, value);
        }
        private string _DeleteNameId;

        public string DeleteNameId
        {
            get => _DeleteNameId;
            set => SetProperty(ref _DeleteNameId, value);
        }
        private string _StatisticProjectCount;

        public string StatisticProjectCount
        {
            get => _StatisticProjectCount;
            set => SetProperty(ref _StatisticProjectCount, value);
        }
        private string _StatisticSubtitleCount;
        public string StatisticSubtitleCount
        {
            get => _StatisticSubtitleCount;
            set => SetProperty(ref _StatisticSubtitleCount, value);
        }
        private ObservableCollection<SearchSubtitle> _StatisticSubtitleList =
            new ObservableCollection<SearchSubtitle>();

        public ObservableCollection<SearchSubtitle> StatisticSubtitleList
        {
            get => _StatisticSubtitleList;
            set => SetProperty(ref _StatisticSubtitleList, value);
        }

        private SearchSubtitle4UI _AllSubtitleSelected;

        public SearchSubtitle4UI AllSubtitleSelected
        {
            get => _AllSubtitleSelected;
            set => SetProperty(ref _AllSubtitleSelected, value);
        }

        /// <summary>
        /// 是否是批量导入
        /// </summary>
        private bool _BatchImportChecked = false;

        public bool BatchImportChecked
        {
            get => _BatchImportChecked;
            set => SetProperty(ref _BatchImportChecked, value);
        }

        /// <summary>
        /// 批量导入复选框是否显示
        /// </summary>
        private Visibility _BatchImportVisibility = Visibility.Visible;

        public Visibility BatchImportVisibility
        {
            get => _BatchImportVisibility;
            set => SetProperty(ref _BatchImportVisibility, value);
        }

        /// <summary>
        /// 导入按钮是否可用
        /// </summary>
        private bool _ImportSubtitleEnabled = false;

        public bool ImportSubtitleEnabled
        {
            get => _ImportSubtitleEnabled;
            set => SetProperty(ref _ImportSubtitleEnabled, value);
        }

        private string _ImportAddress;
        public string ImportAddress
        {
            get => _ImportAddress;
            set => SetProperty(ref _ImportAddress, value);
        }

        private string _ImportFolder;
        public string ImportFolder
        {
            get => _ImportFolder;
            set => SetProperty(ref _ImportFolder, value);
        }
        private string _ImportMessage;
        public string ImportMessage
        {
            get => _ImportMessage;
            set => SetProperty(ref _ImportMessage, value);
        }

        private ObservableCollection<SubtitleImport> _ImportFileList =
            new ObservableCollection<SubtitleImport>();

        public ObservableCollection<SubtitleImport> ImportFileList
        {
            get => _ImportFileList;
            set => SetProperty(ref _ImportFileList, value);
        }

        private ObservableCollection<VideoType> _VideoTypes = new ObservableCollection<VideoType>();

        public ObservableCollection<VideoType> VideoTypes
        {
            get => _VideoTypes;
            set => SetProperty(ref _VideoTypes, value);
        }
        private VideoType _VideoType = VideoType.TV;
        public VideoType VideoType
        {
            get => _VideoType;
            set => SetProperty(ref _VideoType, value);
        }
        ISubtitleImportService importService = new SubtitleImportTvService();
        private int doneCount = 0;

        private ObservableCollection<string> _SearchNameHistorys =
            new ObservableCollection<string>();
        public ObservableCollection<string> SearchNameHistorys
        {
            get => _SearchNameHistorys;
            set { SetProperty(ref _SearchNameHistorys, value); }
        }

        private ObservableCollection<string> _SearchHistorys = new ObservableCollection<string>();
        public ObservableCollection<string> SearchHistorys
        {
            get => _SearchHistorys;
            set { SetProperty(ref _SearchHistorys, value); }
        }

        private ObservableCollection<string> _NameHistorys = new ObservableCollection<string>();
        public ObservableCollection<string> NameHistorys
        {
            get => _NameHistorys;
            set { SetProperty(ref _NameHistorys, value); }
        }

        private ObservableCollection<string> _VideoHistorys = new ObservableCollection<string>();
        public ObservableCollection<string> VideoHistorys
        {
            get => _VideoHistorys;
            set { SetProperty(ref _VideoHistorys, value); }
        }
    }
}
